#include"StdAfx.h"

pgMouseInputManager::pgMouseInputManager()
{
	m_pEventData = NULL;
	m_pEvent = NULL;

	m_nButtonStates = 0;

	m_pEvent = new IEvent();
	m_pEventData = new SEventData_MouseEvent();

	m_keyMap[VK_LBUTTON] = eMB_Left;
	m_keyMap[VK_RBUTTON] = eMB_Right;
	m_keyMap[VK_MBUTTON] = eMB_Middle;
	m_keyMap[VK_XBUTTON1] = eMB_X1;
	m_keyMap[VK_XBUTTON2] = eMB_X2;
}
pgMouseInputManager::~pgMouseInputManager()
{
}

void pgMouseInputManager::Update(float frameTime)
{
}
void pgMouseInputManager::RegisterListener(IEventListener *listener, EVENT_CLASS eventClass, EVENT_NAME eventName)
{
	if (listener)
	{
		m_listeners.push_back(listener);
	}
	else
	{
		PG_LOG_WARNING_EX(TOPIC_MOUSE_INPUT_MANAGER, "Trying to register a null listener!");
	}
}
void pgMouseInputManager::UnregisterListener(IEventListener *listener)
{
	if (!listener)
	{
		PG_LOG_WARNING_EX(TOPIC_MOUSE_INPUT_MANAGER, "Trying to unregister a null listener!");
		return;
	}

	std::list<IEventListener*>::iterator iter = m_listeners.begin();
	bool bFound = false;
	while(iter != m_listeners.end())
	{
		if (listener->id == (*iter)->id)
		{
			bFound = true;
			break;
		}
		++iter;
	}

	if (bFound)
		m_listeners.remove((*iter));
	else
		PG_LOG_WARNING_EX(TOPIC_MOUSE_INPUT_MANAGER, "Couldn't find listener: %d for unregistering!", listener->id);
}
void pgMouseInputManager::RegisterEvent(int eventName, int eventClass, IEventData *pData)
{
	if (eventClass == EMouseEventClasses::eME_Move)
		ProcessMovement(eventName);
	else
	{
		ProcessButtons(eventName, eventClass);
		m_pEvent->eventId = m_keyMap[eventName];
		m_pEvent->eventClass = eventClass;
	}


	m_pEventData->m_nButtonStates = m_nButtonStates;

	DispatchEvent();
}
void pgMouseInputManager::ShutDown()
{
	// m_pEventData will be deleted by m_pEvent
	PG_SAFE_DELETE(m_pEvent);
	
}

bool pgMouseInputManager::IsButtonPressed(int id)
{
	if (m_nButtonStates & id)
		return true;
	else
		return false;
}
bool pgMouseInputManager::IsButtonTapped(int id)
{
	if (IsButtonPressed(id))
	{
		m_nButtonStates &= ~id;
		return true;
	}
	else
		return false;
}

void pgMouseInputManager::DispatchEvent()
{
	std::list<IEventListener*>::iterator it;

	m_pEvent->pData = m_pEventData;

	for (it = m_listeners.begin(); it != m_listeners.end(); ++it)
	{
		(*it)->OnEvent(m_pEvent);
	}

	// POSSIBLE FAIL
	// Maybe wheel data must be processed better before sending it. One click equals 120
	// 
	m_pEventData->m_nMWheelDelta = 0;
}

void pgMouseInputManager::ProcessMovement(int lParam)
{
	m_pEventData->m_nDeltaX = GET_X_LPARAM(lParam) - m_nLastX;
	m_pEventData->m_nDeltaY = GET_Y_LPARAM(lParam) - m_nLastY;

	m_nLastX = GET_X_LPARAM(lParam);
	m_nLastY = GET_Y_LPARAM(lParam);
}

void pgMouseInputManager::ProcessButtons(int buttonId, int activationMode)
{
	if (activationMode == eME_ButtonClicked)
	{
		m_nButtonStates |= m_keyMap[buttonId];
	}
	else if (activationMode == eME_ButtonReleased) 
	{
		m_nButtonStates &= ~m_keyMap[buttonId];
	}
	else if (activationMode == eME_WheelV)
	{
		m_pEventData->m_nMWheelDelta = GET_WHEEL_DELTA_WPARAM(buttonId);
	}
}